/**
 * 
 */
package fr.gfi.agraf.persistence.dao.impl;

import java.util.HashSet;
import java.util.Set;

import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.springframework.stereotype.Repository;

import fr.gfi.agraf.persistence.dao.IPoiPerimetreDAO;
import fr.gfi.agraf.vue.bean.ActiviteDTO;
import fr.gfi.agraf.vue.bean.PerimetreDTO;
import fr.gfi.agraf.vue.bean.TacheDTO;
import fr.gfi.agraf.vue.bean.UtilisateurDTO;

/**
 * @author Zakaria
 * 
 */
@Repository
public class PoiPerimetreDAO implements IPoiPerimetreDAO {

	public static final String NOM_FEUILLE_CHARGES = "Détail des charges";

	private CellStyle enteteStyle;
	private CellStyle bodyStyle1;
	private CellStyle bodyStyle2;

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * fr.gfi.agraf.persistence.dao.IPoiPerimetreDAO#writePerimetre(fr.gfi.agraf
	 * .persistence.entity.Perimetre)
	 */
	public HSSFWorkbook writePerimetre(final PerimetreDTO perimetre) {
		final HSSFWorkbook workbook = new HSSFWorkbook();
		enteteStyle = workbook.createCellStyle();
		bodyStyle1 = workbook.createCellStyle();
		bodyStyle2 = workbook.createCellStyle();
		final HSSFFont font = workbook.createFont();
		font.setColor(HSSFColor.WHITE.index);
		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		enteteStyle.setFont(font);
		enteteStyle.setFillForegroundColor(HSSFColor.GREY_80_PERCENT.index);
		enteteStyle.setFillPattern((short) 1);
		bodyStyle1.setFillForegroundColor(HSSFColor.WHITE.index);
		bodyStyle1.setFillPattern((short) 1);
		bodyStyle2.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index);
		bodyStyle2.setFillPattern((short) 1);

		// Créé feuille de résumé des charges
		creerFeuilleResume(workbook, perimetre);

		// Créé feuille détail des charges
		creerFeuilleDetailCharges(workbook, perimetre);

		return workbook;
	}

	/**
	 * Creer la deuxieme feuille de l'export
	 */
	private void creerFeuilleDetailCharges(final HSSFWorkbook workbook,
			final PerimetreDTO perimetre) {
		final HSSFSheet sheet = workbook.createSheet(NOM_FEUILLE_CHARGES);
		creerEnteteCharges(sheet, enteteStyle);
		int numRow = 5;
		for (final ActiviteDTO activite : perimetre.getListeActivite()) {
			numRow++;
			CellStyle bodyStyle = bodyStyle1;
			// Créé une ligne pour chaque activité
			final Row rowActivite = sheet.createRow(numRow);
			createCell(activite.getLibelle(), bodyStyle, rowActivite, 2);
			Double chargeTotale = 0d;
			// Récupere les données necessaires
			for (final TacheDTO tache : activite.getTacheList()) {
				chargeTotale += tache.getChargeInit();
			}
			createCell("Total :", bodyStyle, rowActivite, 6);
			createCell(chargeTotale, bodyStyle, rowActivite, 7);
			// Ensuite je crée une ligne pour chaque taches
			for (final TacheDTO tache : activite.getTacheList()) {
				numRow++;
				bodyStyle = bodyStyle1;
				final Row rowTache = sheet.createRow(numRow);
				createCell(tache.getLibelle(), bodyStyle, rowTache, 3);
				createCell(tache.getChargeInit(), bodyStyle, rowTache, 6);
				createCell(tache.getCommentaire(), bodyStyle, rowTache, 8);
			}
		}

		// Evalue toute les cellules
		HSSFFormulaEvaluator.evaluateAllFormulaCells(workbook);
		final HSSFRow row = sheet.getRow(6);
		if (row != null) {
			for (int i = 0; i < row.getPhysicalNumberOfCells(); i++) {
				sheet.autoSizeColumn(i, true);
			}
		}
	}

	/**
	 * Cree l'entete de la deuxieme feuille de l'export
	 */
	private void creerEnteteCharges(final HSSFSheet sheet, CellStyle style) {
		// Créé une nouvelle ligne
		final Row row = sheet.createRow(5);
		// Créé une nouvelle cellule dans la ligne
		createCell("Activités", enteteStyle, row, 2);
		createCell("Tâches", enteteStyle, row, 3);
		createCell("Complexité", enteteStyle, row, 4);
		createCell("Création / Modification", enteteStyle, row, 5);
		createCell("Charge init", enteteStyle, row, 6);
		createCell("Partie", enteteStyle, row, 7);
		createCell("Remarques", enteteStyle, row, 8);
	}

	/**
	 * Creer la premiere feuille de résumé du périmetre
	 * 
	 * @param workbook
	 * @param perimetre
	 */
	private void creerFeuilleResume(final HSSFWorkbook workbook,
			final PerimetreDTO perimetre) {
		final HSSFSheet sheet = workbook.createSheet(perimetre.getLibelle());
		creerEntete(sheet, enteteStyle);
		int numRow = 2;
		for (final ActiviteDTO activite : perimetre.getListeActivite()) {
			numRow++;
			CellStyle bodyStyle = bodyStyle1;
			if (numRow % 2 == 0) {
				bodyStyle = bodyStyle2;
			}
			// Créé une ligne pour chaque activité
			final Row rowActivite = sheet.createRow(numRow);
			createCell(activite.getLibelle(), bodyStyle, rowActivite, 2);
			Double chargeTotale = 0d;
			Double rafTotale = 0d;
			Double consommeTotale = 0d;
			// Récupere les données necessaires
			final Set<String> utilisateurSet = new HashSet<String>();
			for (final TacheDTO tache : activite.getTacheList()) {
				chargeTotale += tache.getChargeInit();
				rafTotale += tache.getRaf();
				consommeTotale += tache.getConsommeTotal();
				final UtilisateurDTO utilisateur = tache.getUtilisateur();
				if (utilisateur != null) {
					utilisateurSet.add(utilisateur.getNom() + " "
							+ utilisateur.getPrenom());
				}
			}
			createCell(chargeTotale, bodyStyle, rowActivite, 3);
			createCell(rafTotale, bodyStyle, rowActivite, 4);
			createCell(consommeTotale, bodyStyle, rowActivite, 5);
			createCell(chargeTotale - consommeTotale + rafTotale, bodyStyle, rowActivite, 6);
			createCell(activite.getEtat().getLibelle(), bodyStyle, rowActivite,
					7);
			createCell(utilisateurSet.toString().replaceAll("[\\[\\]]", ""),
					bodyStyle, rowActivite, 8);
			createCell(activite.getRemarque(), bodyStyle, rowActivite, 9);
		}

		// Evalue toute les cellules
		HSSFFormulaEvaluator.evaluateAllFormulaCells(workbook);
		final HSSFRow row = sheet.getRow(2);
		if (row != null) {
			for (int i = 0; i < row.getPhysicalNumberOfCells(); i++) {
				sheet.autoSizeColumn(i, true);
			}
		}
	}

	/**
	 * Creer la premiere ligne
	 * 
	 * @param sheet
	 */
	private void creerEntete(final HSSFSheet sheet, final CellStyle enteteStyle) {
		// Créé une nouvelle ligne
		final Row row = sheet.createRow(2);
		// Créé une nouvelle cellule dans la ligne
		createCell("Activités", enteteStyle, row, 2);
		createCell("Charges", enteteStyle, row, 3);
		createCell("RAF", enteteStyle, row, 4);
		createCell("Consomme", enteteStyle, row, 5);
		createCell("Derive", enteteStyle, row, 6);
		createCell("Etat", enteteStyle, row, 7);
		createCell("Developpeurs", enteteStyle, row, 8);
		createCell("Remarques", enteteStyle, row, 9);
	}

	/**
	 * Créer une cellule avec un style à une ligne donnée STRING
	 * 
	 * @param enteteStyle
	 * @param row
	 */
	private void createCell(final String contenu, final CellStyle enteteStyle,
			final Row row, final int cellNumber) {
		final Cell cell6 = row.createCell(cellNumber);
		cell6.setCellValue(contenu);
		cell6.setCellStyle(enteteStyle);
	}

	/**
	 * Créer une cellule avec un style à une ligne donnée DOUBLE
	 * 
	 * @param enteteStyle
	 * @param row
	 */
	private void createCell(final Double contenu, final CellStyle enteteStyle,
			final Row row, final int cellNumber) {
		final Cell cell6 = row.createCell(cellNumber);
		cell6.setCellValue(contenu);
		cell6.setCellStyle(enteteStyle);
	}

}
